package com.holly.unit.bpmn.modular.activiti.controller;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.holly.unit.bpmn.designer.core.facade.BpmnDesignerFacadeApi;
import com.holly.unit.bpmn.designer.model.*;
import com.holly.unit.bpmn.designer.service.ActivitiZDesignerService;
import com.holly.unit.core.pojo.response.ResponseData;
import com.holly.unit.core.pojo.response.SuccessResponseData;
import com.holly.unit.scanner.api.annotation.ApiResource;
import com.holly.unit.scanner.api.annotation.GetResource;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 类描述: 流程设计器测试类
 *
 * @author fxr
 * @version 1.0.0
 * @date 2022/5/17 13:12
 */
@RestController
@ApiResource(name = "流程设计器相关API")
@Api(tags = "流程设计器相关API")
@Slf4j
public class BpmnDesignerController {

    @Resource
    private BpmnDesignerFacadeApi designerApi;

    @Resource
    private ActivitiZDesignerService designerService;

    /**
     * <?xml version="1.0" encoding="UTF-8"?>

     -<definitions targetNamespace="http://www.activiti.org/test" expressionLanguage="http://www.w3.org/1999/XPath" typeLanguage="http://www.w3.org/2001/XMLSchema" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:activiti="http://activiti.org/bpmn" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL">


     -<process isExecutable="true" name="请假流程测试" id="abc_fc89c365-583c-4f51-b0f0-1b5e2d6928c1_code">

     <startEvent name="请假流程测试" id="node_95001"/>

     <endEvent id="end"/>

     <userTask name="提交表单" id="node_95002" activiti:candidateGroups="workflowManager"/>

     <userTask name="提交确认" id="node_95003" activiti:candidateUsers="${auditAssignee}"/>

     <userTask name="财务审批" id="node_95004" activiti:candidateGroups="workflowManager"/>

     <userTask name="组长审批" id="node_95005" activiti:candidateUsers="${auditAssignee}"/>

     <exclusiveGateway id="node_95003-gateway"/>

     <sequenceFlow id="sequenceFlow-4bd6884d-a9a9-4645-9934-a92859d6b75c" targetRef="node_95003" sourceRef="node_95002"/>

     <sequenceFlow id="sequenceFlow-ce64b788-eeaa-4406-a544-e7ef33373e7d" targetRef="node_95003-gateway" sourceRef="node_95003"/>

     <sequenceFlow id="sequenceFlow-90a939de-0131-453a-817d-846664b8773f" targetRef="end" sourceRef="node_95004"/>

     <sequenceFlow id="sequenceFlow-1a11c576-126f-48bd-8490-cb2f60bd9d47" targetRef="node_95004" sourceRef="node_95005"/>


     -<sequenceFlow name="审批完成" id="sequenceFlow-3e148d5d-59a5-4f18-96bb-8133193eb7fd" targetRef="node_95004" sourceRef="node_95003-gateway">


     -<conditionExpression xsi:type="tFormalExpression">

     -<![CDATA[${name < '3'}]]>
     </conditionExpression>

     </sequenceFlow>


     -<sequenceFlow name="再次审批" id="sequenceFlow-aad249ff-bb3d-435c-bf4f-1cc26c10027e" targetRef="node_95005" sourceRef="node_95003-gateway">


     -<conditionExpression xsi:type="tFormalExpression">

     -<![CDATA[${name >= '3'}]]>
     </conditionExpression>

     </sequenceFlow>

     <sequenceFlow id="sequenceFlow-a65cc697-3a51-443f-973f-fabab9ca8857" targetRef="node_95002" sourceRef="node_95001"/>

     </process>


     -<bpmndi:BPMNDiagram id="BPMNDiagram_abc_fc89c365-583c-4f51-b0f0-1b5e2d6928c1_code">


     -<bpmndi:BPMNPlane id="BPMNPlane_abc_fc89c365-583c-4f51-b0f0-1b5e2d6928c1_code" bpmnElement="abc_fc89c365-583c-4f51-b0f0-1b5e2d6928c1_code">


     -<bpmndi:BPMNShape id="BPMNShape_node_95005" bpmnElement="node_95005">

     <omgdc:Bounds y="100.0" x="470.0" width="100.0" height="60.0"/>

     </bpmndi:BPMNShape>


     -<bpmndi:BPMNShape id="BPMNShape_node_95003" bpmnElement="node_95003">

     <omgdc:Bounds y="42.0" x="230.0" width="100.0" height="60.0"/>

     </bpmndi:BPMNShape>


     -<bpmndi:BPMNShape id="BPMNShape_node_95004" bpmnElement="node_95004">

     <omgdc:Bounds y="36.0" x="620.0" width="100.0" height="60.0"/>

     </bpmndi:BPMNShape>


     -<bpmndi:BPMNShape id="BPMNShape_node_95001" bpmnElement="node_95001">

     <omgdc:Bounds y="59.0" x="0.0" width="30.0" height="30.0"/>

     </bpmndi:BPMNShape>


     -<bpmndi:BPMNShape id="BPMNShape_node_95002" bpmnElement="node_95002">

     <omgdc:Bounds y="44.0" x="80.0" width="100.0" height="60.0"/>

     </bpmndi:BPMNShape>


     -<bpmndi:BPMNShape id="BPMNShape_end" bpmnElement="end">

     <omgdc:Bounds y="51.0" x="770.0" width="30.0" height="30.0"/>

     </bpmndi:BPMNShape>


     -<bpmndi:BPMNShape id="BPMNShape_node_95003-gateway" bpmnElement="node_95003-gateway">

     <omgdc:Bounds y="48.0" x="380.0" width="40.0" height="40.0"/>

     </bpmndi:BPMNShape>


     -<bpmndi:BPMNEdge id="BPMNEdge_sequenceFlow-90a939de-0131-453a-817d-846664b8773f" bpmnElement="sequenceFlow-90a939de-0131-453a-817d-846664b8773f">

     <omgdi:waypoint y="66.0" x="720.0"/>

     <omgdi:waypoint y="66.0" x="770.0"/>

     </bpmndi:BPMNEdge>


     -<bpmndi:BPMNEdge id="BPMNEdge_sequenceFlow-3e148d5d-59a5-4f18-96bb-8133193eb7fd" bpmnElement="sequenceFlow-3e148d5d-59a5-4f18-96bb-8133193eb7fd">

     <omgdi:waypoint y="60.5" x="420.0"/>

     <omgdi:waypoint y="60.5" x="432.0"/>

     <omgdi:waypoint y="66.0" x="432.0"/>

     <omgdi:waypoint y="66.0" x="620.0"/>

     </bpmndi:BPMNEdge>


     -<bpmndi:BPMNEdge id="BPMNEdge_sequenceFlow-1a11c576-126f-48bd-8490-cb2f60bd9d47" bpmnElement="sequenceFlow-1a11c576-126f-48bd-8490-cb2f60bd9d47">

     <omgdi:waypoint y="130.0" x="570.0"/>

     <omgdi:waypoint y="130.0" x="582.0"/>

     <omgdi:waypoint y="66.0" x="582.0"/>

     <omgdi:waypoint y="66.0" x="620.0"/>

     </bpmndi:BPMNEdge>


     -<bpmndi:BPMNEdge id="BPMNEdge_sequenceFlow-aad249ff-bb3d-435c-bf4f-1cc26c10027e" bpmnElement="sequenceFlow-aad249ff-bb3d-435c-bf4f-1cc26c10027e">

     <omgdi:waypoint y="75.5" x="420.0"/>

     <omgdi:waypoint y="75.5" x="432.0"/>

     <omgdi:waypoint y="130.0" x="432.0"/>

     <omgdi:waypoint y="130.0" x="470.0"/>

     </bpmndi:BPMNEdge>


     -<bpmndi:BPMNEdge id="BPMNEdge_sequenceFlow-ce64b788-eeaa-4406-a544-e7ef33373e7d" bpmnElement="sequenceFlow-ce64b788-eeaa-4406-a544-e7ef33373e7d">

     <omgdi:waypoint y="72.0" x="330.0"/>

     <omgdi:waypoint y="72.0" x="342.0"/>

     <omgdi:waypoint y="68.0" x="342.0"/>

     <omgdi:waypoint y="68.0" x="380.0"/>

     </bpmndi:BPMNEdge>


     -<bpmndi:BPMNEdge id="BPMNEdge_sequenceFlow-4bd6884d-a9a9-4645-9934-a92859d6b75c" bpmnElement="sequenceFlow-4bd6884d-a9a9-4645-9934-a92859d6b75c">

     <omgdi:waypoint y="74.0" x="180.0"/>

     <omgdi:waypoint y="74.0" x="192.0"/>

     <omgdi:waypoint y="72.0" x="192.0"/>

     <omgdi:waypoint y="72.0" x="230.0"/>

     </bpmndi:BPMNEdge>


     -<bpmndi:BPMNEdge id="BPMNEdge_sequenceFlow-a65cc697-3a51-443f-973f-fabab9ca8857" bpmnElement="sequenceFlow-a65cc697-3a51-443f-973f-fabab9ca8857">

     <omgdi:waypoint y="74.0" x="30.0"/>

     <omgdi:waypoint y="74.0" x="80.0"/>

     </bpmndi:BPMNEdge>

     </bpmndi:BPMNPlane>

     </bpmndi:BPMNDiagram>

     </definitions>
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     * */












    @ApiOperation("流程设计器接口测试")
    @GetResource(name = "流程设计器接口测试", path = "/bpmnDesigner/test",requiredPermission = false,requiredLogin = false)
    public ResponseData test() {
        // 1.创建基本信息
        BasicInfo basic = BasicInfo.builder()
                .id("abc_"+IdUtil.randomUUID())
                .name("请假流程测试")
                .remark("简单测试流程设计器")
                .background("背景颜色")
                .icon("流程图标")
                .code("abc_"+IdUtil.randomUUID()+"_code")
                // 流程分组
                .group(95001)
                .build();

        // 1.创建表单设计器信息
        String formDataJson = "";
        JSONObject formData = JSON.parseObject(formDataJson,JSONObject.class);

        // 3.创建流程设计信息
        ProcessInfo processInfo = new ProcessInfo();
        processInfo.setType("start");//开始
        processInfo.setContent("所有人");
        // 设置根节点配置的属性信息

        RootProperties rootProperties = RootProperties.builder().initiator("all")
                .title("发起人")
                .columns(setFormColContrl()) // 表单字段权限
                .btns(setBtns())
                .build();
        processInfo.setProperties(rootProperties);
        processInfo.setChildNode(setFirstChildNode());

        processInfo.setNodeId("node_95001");
        processInfo.setPrevId(null);
        processInfo.setConditionNodes(null);







        // 4.把三部分信息设置为流程设计器领域模型
        BpmnDesignerModel model = new BpmnDesignerModel();
        model.setBasicInfo(basic);
        model.setFormData(formData);
        model.setProcessInfo(processInfo);

        // 5.调用流程设计器高层部署接口，部署流程
        boolean deploy = designerApi.deploy(model);
        return new SuccessResponseData(deploy);
    }




    private ChildNode setFirstChildNode() {

        ChildNode childNode = new ChildNode();

        childNode.setType("approver");
        childNode.setPrevId("node_95001");
        childNode.setNodeId("node_95002");
        childNode.setContent("工单负责人");
        childNode.setConditionNodes(null);
        childNode.setOuterNodeId(null);
        ChildProperties childProperties = new ChildProperties();
        TreeSelectModel treeSelectModel = new TreeSelectModel();
        treeSelectModel.setChildren(null);
        treeSelectModel.setHasChild(null);
        treeSelectModel.setIcon("icon-ym icon-ym-tree-user2");
        treeSelectModel.setName("组长负责人");
        treeSelectModel.setPid("-1");
        treeSelectModel.setType("role");
        treeSelectModel.setId("workflowManager");

        List<TreeSelectModel> listRole = new ArrayList<>();

        listRole.add(treeSelectModel);
        childProperties.setApproverRoles(listRole);


        List<TreeSelectModel> listApprovers = new ArrayList<>();
        childProperties.setApprovers(listApprovers);
        childProperties.setAssigneeType("role");
        childProperties.setExpression("");

        List<FormColControl> colControls = new ArrayList<>();
        colControls.add(setFormColContrl());

        childProperties.setFormColControls(colControls);
        List<BtnControl> btns = new ArrayList<>();
        childProperties.setBtnControls(btns);

        childProperties.setOptionalMultiUser("orSign");
        childProperties.setTitle("提交表单");

        childNode.setProperties(childProperties);

        childNode.setChildNode(setSecondChildNode());


        return childNode;

    }

    private ChildNode setSecondChildNode() {
        ChildNode childNode = new ChildNode();
        // 设置子节点
        childNode.setChildNode(setThreeChildNode());
        childNode.setContent("自定义");
        childNode.setNodeId("node_95003");
        childNode.setOuterNodeId(null);
        childNode.setPrevId("node_95002");
        childNode.setType("approver");

        // 设置条件节点1

        List<ConditionNode> conditionNodes = new ArrayList<>();
        ConditionNode conditionNode1 = new ConditionNode();

        conditionNode1.setChildNode(null);
        conditionNode1.setConditionNodes(null);
        conditionNode1.setContent("审批完成");
        conditionNode1.setNodeId("line_condition_95007");
        conditionNode1.setPrevId("node_95003");
        conditionNode1.setType("condition");

        ConditionProperties conditionProperties = new ConditionProperties();
        conditionProperties.setCondition("${name < '3'}");
        conditionProperties.setConditionLebel("审批完成");
        List<Conditions> conditions = new ArrayList<>();
        Conditions con = new Conditions();
        con.setCondition("${name < '3'}");
        con.setConditionLebel("审批完成");
        conditions.add(con);
        conditionProperties.setConditions(conditions);
        conditionProperties.setInitiator(null);
        conditionProperties.setIsDefault(false);
        conditionProperties.setPriority(0);
        conditionProperties.setTitle("直接审批");
        conditionNode1.setProperties(conditionProperties);
        conditionNodes.add(conditionNode1);

        // 设置条件节点2
        ConditionNode conditionNode2 = new ConditionNode();

        conditionNode2.setChildNode(setCC());
        conditionNode2.setConditionNodes(null);
        conditionNode2.setContent("再次审批");
        conditionNode2.setNodeId("line_condition_95006");
        conditionNode2.setPrevId("node_95003");
        conditionNode2.setType("condition");

        ConditionProperties tmpP = new ConditionProperties();
        tmpP.setCondition("${name >= '3'}");
        tmpP.setConditionLebel("再次审批");
        List<Conditions> list = new ArrayList<>();
        Conditions c = new Conditions();
        c.setCondition("${name >= '3'}");
        c.setConditionLebel("再次审批");
        list.add(c);
        tmpP.setConditions(list);
        tmpP.setInitiator(null);
        tmpP.setIsDefault(false);
        tmpP.setPriority(1);
        tmpP.setTitle("二次审批");
        conditionNode2.setProperties(tmpP);

        conditionNodes.add(conditionNode2);

        childNode.setConditionNodes(conditionNodes);

        // 设置childNode 节点的properties
        ChildProperties childProperties = new ChildProperties();
        childProperties.setApproverRoles(new ArrayList<>());
        childProperties.setApprovers(new ArrayList<>());
        childProperties.setAssigneeType("input");
        childProperties.setExpression("${auditAssignee}");
        childProperties.setFormColControls(new ArrayList<>());
        childProperties.setBtnControls(new ArrayList<>());
        childProperties.setOptionalMultiUser("orSign");
        childProperties.setTitle("提交确认");
        childNode.setProperties(childProperties);

        return childNode;
    }

    private ChildNode setCC() {
        ChildNode cc = new ChildNode();
        cc.setChildNode(null);
        cc.setConditionNodes(null);
        cc.setContent("自定义");
        cc.setNodeId("node_95005");
        cc.setOuterNodeId(null);
        cc.setPrevId("line_condition_95006");
        cc.setType("approver");

        ChildProperties pp = new ChildProperties();
        pp.setApproverRoles(new ArrayList<>());
        pp.setApprovers(new ArrayList<>());
        pp.setAssigneeType("input");
        pp.setExpression("${auditAssignee}");
        pp.setFormColControls(new ArrayList<>());
        pp.setBtnControls(new ArrayList<>());
        pp.setOptionalMultiUser("orSign");
        pp.setTitle("组长审批");
        cc.setProperties(pp);

        return cc;


    }

    private ChildNode setThreeChildNode() {
        ChildNode childNode = new ChildNode();
        childNode.setChildNode(null);
        childNode.setConditionNodes(null);
        childNode.setContent("组长负责人");
        childNode.setNodeId("node_95004");
        childNode.setOuterNodeId(null);
        childNode.setPrevId("node_95003");
        childNode.setType("approver");

        ChildProperties childProperties = new ChildProperties();

        TreeSelectModel treeSelectModel = new TreeSelectModel();
        treeSelectModel.setChildren(null);
        treeSelectModel.setHasChild(null);
        treeSelectModel.setIcon("icon-ym icon-ym-tree-user2");
        treeSelectModel.setName("组长负责人");
        treeSelectModel.setPid("-1");
        treeSelectModel.setType("role");
        treeSelectModel.setId("workflowManager");

        List<TreeSelectModel> listRole = new ArrayList<>();

        listRole.add(treeSelectModel);

        childProperties.setApproverRoles(listRole);

        childProperties.setApprovers(new ArrayList<>());

        childProperties.setAssigneeType("role");

        childProperties.setExpression("");
        List<FormColControl> colControls = new ArrayList<>();
        colControls.add(setFormColContrl());
        childProperties.setFormColControls(colControls);
        childProperties.setBtnControls(new ArrayList<>());
        childProperties.setOptionalMultiUser("orSign");
        childProperties.setTitle("财务审批");

        childNode.setProperties(childProperties);

        return childNode;
    }

    private BtnControl setBtns() {
        BtnControl btnControl = new BtnControl();
        return btnControl;
    }

    private FormColControl setFormColContrl() {

        FormColControl formColContrl = new FormColControl();
        formColContrl.setFormId("108");
        formColContrl.setLebel("姓名");
        formColContrl.setRead(true);
        formColContrl.setRequired(true);
        formColContrl.setVModel("name");
        formColContrl.setWrite(false);

        return formColContrl;

    }

}
